package com.qf.proxy;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;

/**
 * 我的切面实现类 （自定义实现类）
 * <p>
 * 1、前置
 * 2、后置
 * 3、异常
 * 4、环绕
 *
 * @author lixu
 * @Component : 类似于@Haha <bean class=包类.MyAspect实例化了
 * <p>
 * 语义：@Haha：业务逻辑开发层
 * @Component： 切面 User POJO对象  跟业务无关的其它的对象需要实例化的时候使用的注解
 * @Aspect : 切面实现类注解  打此注解表示当前类是切面实现类（动态代理类）
 * 前提： spring-context.xml   <aop:aspectj-autoproxy/>
 */
@Component
@Aspect
public class MyAspect {

    //公共的抽取出来
    @Pointcut(value = "execution(public * com.qf.service.UserServiceImpl.zufang(..))")
    public void pc(){}


    //     *    1、前置
    @Before(value = "pc()")
    public void beforeAdvice(JoinPoint jp) {
        Object[] args = jp.getArgs();
        args[0] = "gp1000000";


        System.out.println("====1：找中介==");
        System.out.println("====2：中介带看房==");
    }

    // *    2、后置
    @AfterReturning(value = "pc()",returning = "r")
    public void afterAdvice(JoinPoint jp,Object r) {
        Object[] args = jp.getArgs();
        System.out.println("核心方法的返回值:" + r);
        System.out.println("====3：维修==");
        System.out.println("====4：转租==");
    }

    // *    3、异常
    @AfterThrowing(value = "pc()",throwing = "ex")
    public void throwAdvice(JoinPoint jp,Exception ex) {
        System.out.println("====抛出异常==:" + ex.getMessage());
    }



// *    4、环绕
    @Around(value = "pc()")
    public Object aroundAdvice(ProceedingJoinPoint pjp){

        //1:我想知道是哪个方法切过来的

        //Signature：签名   Java切面：类路径叫签名   包名+类名 + 方法名 + 形参
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method method = methodSignature.getMethod();
        Class returnType = methodSignature.getReturnType();
        System.out.println(method.toString());

        Override override = method.getAnnotation(Override.class);
        Transactional transactional = method.getAnnotation(Transactional.class);

        System.out.println("====1：找中介==");
        System.out.println("====2：中介带看房==");

        Object[] args = pjp.getArgs();
        Object name = args[0];
        System.out.println("aroundAdvice==接收到的参数是:" + name);
        args[0] = "gp10000000";
        Object result = null;
        try {
            //回到核心代码
            result = pjp.proceed(args);//抛出异常
            System.out.println("aroundAdvice====:返回值:" + result);
            System.out.println("====3：维修==");
            System.out.println("====4：转租==");
            return "我不是房东";
        } catch (Throwable throwable) {
            throwable.printStackTrace();//打印异常在栈中的信息
            //
            System.out.println("===核心代码出异常：" + throwable.getMessage());//打印异常信息
        }

        return null;
    }


}
